package com.example.administrator.im.ui.activity;

import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.example.administrator.im.R;
import com.example.administrator.im.adapter.WeatherAdapter;
import com.example.administrator.im.db.CityDBHelper;
import com.example.administrator.im.db.CountyDBHelper;
import com.example.administrator.im.db.ProvinceDBHelper;
import com.example.administrator.im.interfacz.ShareTitleable;
import com.example.administrator.im.ui.fragment.MyFragment;
import com.example.administrator.im.view.ShareTitle;
import com.example.administrator.weather.db.City;
import com.example.administrator.weather.db.County;
import com.example.administrator.weather.db.Province;
import com.example.administrator.weather.gson.Weather;
import com.example.administrator.weather.utils.WeatherHttpUtils;

import org.greenrobot.eventbus.EventBus;
import org.litepal.LitePal;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

public class WeatherActivity extends AppCompatActivity {

    private final String TAG = "WeatherActivity";
    //http://guolin.tech/api/weather?cityid=CN101280103&key=61bc3dddaca14dc4a940aaa7b08edf10

    private TextView tmp;
    private TextView geography;
    private TextView situation;

    private RecyclerView date;
    private WeatherAdapter adapter;

    private TextView aqi;
    private TextView pm2_5;

    private TextView comfort;
    private TextView carWashing;
    private TextView sport;

    private SwipeRefreshLayout swipeRefresh;

    private ShareTitle shareTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        getWindow().setStatusBarColor(Color.TRANSPARENT);

        setContentView(R.layout.activity_weather);

        //申请权限
        List<String> permissions = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            permissions.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if (!permissions.isEmpty()) {
            String[] permission = permissions.toArray(new String[permissions.size()]);
            ActivityCompat.requestPermissions(this, permission, 1);
        } else {
            requestLocation();
        }

        initView();
        adapter = new WeatherAdapter(this, null);
        date.setLayoutManager(new LinearLayoutManager(this));
        date.setAdapter(adapter);

        SharedPreferences spf = getSharedPreferences("weather", Context.MODE_PRIVATE);
        final String content = spf.getString("content", "");
        if (!TextUtils.isEmpty(content)) {
            selectCountyName = spf.getString("county", "");
            street = spf.getString("street", "");

            Weather weather = WeatherHttpUtils.handleWeatherResponse(content);
            updateUI(weather);
        }

        swipeRefresh.setColorSchemeResources(R.color.theme_color, R.color.theme_color);
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                isRefresh = true;
                if (client == null) {
                    requestLocation();
                } else {
                    client.restart();
                }
            }
        });

    }

    private boolean isRefresh = false;

    private void initView() {
        tmp = (TextView) findViewById(R.id.tmp);
        geography = (TextView) findViewById(R.id.address);
        situation = (TextView) findViewById(R.id.situation);

        aqi = (TextView) findViewById(R.id.aqi);
        pm2_5 = (TextView) findViewById(R.id.pm2_5);

        comfort = (TextView) findViewById(R.id.comfort);
        carWashing = (TextView) findViewById(R.id.carWashing);
        sport = (TextView) findViewById(R.id.sport);

        date = (RecyclerView) findViewById(R.id.rv_weather);
        swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.refresh);

        shareTitle = (ShareTitle) findViewById(R.id.weather_toolbar);
        shareTitle.setIconOnClickListener(new ShareTitleable() {
            @Override
            public void left_click(View v) {
                finish();
            }

            @Override
            public void right_click(View v) {
                //自动选择天气
            }
        });
    }

    private LocationClient client;
    private MyLocationListener myListener = new MyLocationListener();

    private void requestLocation() {

        LocationClientOption option = new LocationClientOption();

        //可选，设置发起定位请求的间隔，int类型，单位ms
        //如果设置为0，则代表单次定位，即仅定位一次，默认为0
        //如果设置非0，需设置1000ms以上才有效
        option.setScanSpan(0);

        //可选，设置是否使用gps，默认false
        //使用高精度和仅用设备两种定位模式的，参数必须设置为true
        option.setOpenGps(true);

        //可选，设置是否当GPS有效时按照1S/1次频率输出GPS结果，默认false
//        option.setLocationNotify(true);


        //可选，V7.2版本新增能力
        //如果设置了该接口，首次启动定位时，会先判断当前Wi-Fi是否超出有效期，若超出有效期，会先重新扫描Wi-Fi，然后定位
        option.setWifiCacheTimeOut(5 * 60 * 1000);

        //可选，设置是否需要过滤GPS仿真结果，默认需要，即参数为false
        option.setEnableSimulateGps(false);

        option.setIsNeedAddress(true);

        client = new LocationClient(getApplicationContext());
        client.setLocOption(option);

        //client为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置，请参照类参考中LocationClientOption类的详细说明
        //声明LocationClient类
        client.registerLocationListener(myListener);
        client.start();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0) {
                    for (int result : grantResults) {
                        if (result != PackageManager.PERMISSION_GRANTED) {
                            Toast.makeText(this, "权限不够", Toast.LENGTH_SHORT).show();
                            finish();
                            return;
                        }
                    }
                    requestLocation();
                }
        }
    }

    private ProvinceDBHelper selectProvince;
    private CityDBHelper selectCity;

    private String selectProvinceName = "", selectCityName = "", selectCountyName = "", street = "";

    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //此处的BDLocation为定位结果信息类，通过它的各种get方法可获取定位相关的全部结果
            //以下只列举部分获取地址相关的结果信息
            //更多结果信息获取说明，请参照类参考中BDLocation类中的说明
            String address = location.getAddrStr();    //获取详细地址信息

            selectProvinceName = location.getProvince();    //获取省份
            selectCityName = location.getCity();    //获取城市
            selectCountyName = location.getDistrict();    //获取区县
            street = location.getStreet();    //获取街道信息

            queryProvince();
        }
    }

    private final String address = WeatherHttpUtils.ADDRESS;

    private void queryProvince() {
        List<ProvinceDBHelper> provinces = LitePal.where("provinceName like ?",
                selectProvinceName.substring(0, 1) + "%").find(ProvinceDBHelper.class);
        int count = provinces.size();
        if (count == 0) {
            queryFromServer(address, "province");
            return;
        }
        for (int i = 0; i < count; i++) {
            //匹配字段
            Log.e(TAG, selectProvinceName);
            if (selectProvinceName.contains(provinces.get(i).getProvinceName())) {
                selectProvince = provinces.get(i);
                queryCity();
                return;
            }
        }
    }

    private void queryCity() {

        List<CityDBHelper> cities = LitePal.where("provinceId = ? ",
                selectProvince.getProvinceCode() + "").find(CityDBHelper.class);
        int count = cities.size();
        if (count == 0) {
            queryFromServer(address + "/" + selectProvince.getProvinceCode(), "city");
            return;
        }
        for (int i = 0; i < count; i++) {

            if (selectCityName.contains(cities.get(i).getCityName()) || selectCountyName.contains(cities.get(i).getCityName())) {
                selectCity = cities.get(i);
                queryCounty();
                return;
            }
        }

    }

    private void queryCounty() {

        List<CountyDBHelper> counties = LitePal.where("cityId = ?",
                selectCity.getCityCode() + "").find(CountyDBHelper.class);
        int count = counties.size();
        if (count == 0) {
            queryFromServer(address + "/" + selectProvince.getProvinceCode()
                    + "/" + selectCity.getCityCode(), "county");
            return;
        }
        for (int i = 0; i < count; i++) {
            if (selectCountyName.contains(counties.get(i).getCountyName())) {
                String weather_id = counties.get(i).getWeatherId();
                showData(weather_id);
                return;
            }
        }

        //若该区在和风天气搜索不到
        for (int i = 0; i < count; i++) {
            if (selectCityName.contains(counties.get(i).getCountyName())) {
                String weather_id = counties.get(i).getWeatherId();
                showData(weather_id);
                return;
            }
        }
    }

    private void showData(String weatherId) {

        SharedPreferences spf = getSharedPreferences("weather", Context.MODE_PRIVATE);
        Long time = spf.getLong("time", 0);
        String content = spf.getString("content", "");

        if (!TextUtils.isEmpty(content) && !isRefresh) {
            Long now = System.currentTimeMillis() / 1000 / 60 / 60;
            time = time / 1000 / 60 / 60;

            if (now - time < 1) {  //距离上次更新不超过1小时
                Weather weather = WeatherHttpUtils.handleWeatherResponse(content);
                updateUI(weather);
                return;
            }
        }
        visitWeatherWeb(weatherId);
    }

    private void visitWeatherWeb(String weatherId) {
        String url = WeatherHttpUtils.URL + weatherId + WeatherHttpUtils.KEY;
        WeatherHttpUtils.sendOkHttpRequest1(url, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, e.getMessage());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        swipeRefresh.setRefreshing(false);
                    }
                });

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                String content = response.body().string();
                Weather weather = WeatherHttpUtils.handleWeatherResponse(content);
                if (weather != null && "ok".equals(weather.status)) {
                    SharedPreferences.Editor editor = getSharedPreferences("weather", Context.MODE_PRIVATE).edit();
                    editor.putString("content", content);
                    editor.putString("county", selectCountyName);
                    editor.putString("street", street);
                    editor.putLong("time", System.currentTimeMillis());
                    editor.apply();
                    updateUI(weather);
                }
            }
        });
    }

    private void showTmp(Weather weather) {

        //温度
        tmp.setText(weather.now.temperature);
        //位置
        geography.setText(selectCountyName + "\t" + street);
        //天气情况
        situation.setText(weather.now.more.info);

        adapter.setmList(weather);

        aqi.setText(weather.aqi.city.aqi);
        pm2_5.setText(weather.aqi.city.pm25);

        comfort.setText("舒适度：" + weather.suggestion.comfort.info);
        carWashing.setText("洗车指数：" + weather.suggestion.carWash.info);
        sport.setText("运动指数：" + weather.suggestion.sport.info);

        shareTitle.setTitle(selectCountyName + " " + weather.now.temperature + "℃", Typeface.NORMAL);
    }


    private void updateUI(final Weather weather) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //跟新ui
                swipeRefresh.setRefreshing(false);
                showTmp(weather);
                EventBus.getDefault().post(new MyFragment.UpdateWeather(weather, selectCountyName));
            }
        });
    }


    private void queryFromServer(String address, final String type) {

        WeatherHttpUtils.sendOkHttpRequest1(address, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //加载失败
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                String content = response.body().string();
                if ("province".equals(type)) {  //保存省份的数据
                    List<Province> provinces = WeatherHttpUtils.handleProvinceResponse(content);
                    for (int i = 0; i < provinces.size(); i++) {
                        ProvinceDBHelper provinceDBHelper =
                                new ProvinceDBHelper();
                        provinceDBHelper.setProvinceName(provinces.get(i).getProvinceName());
                        provinceDBHelper.setProvinceCode(provinces.get(i).getProvinceCode());
                        provinceDBHelper.save();
                    }
                    queryProvince();
                } else if ("city".equals(type)) {
                    List<City> cities = WeatherHttpUtils.handleCityResponse(content, selectProvince.getProvinceCode());
                    for (int i = 0; i < cities.size(); i++) {
                        CityDBHelper cityDBHelper = new CityDBHelper();
                        cityDBHelper.setCityName(cities.get(i).getCityName());
                        cityDBHelper.setCityCode(cities.get(i).getCityCode());
                        cityDBHelper.setProvinceId(cities.get(0).getProvinceId());
                        cityDBHelper.save();
                    }
                    queryCity();
                } else if ("county".equals(type)) {
                    List<County> counties = WeatherHttpUtils.handleCountyResponse(content, selectCity.getCityCode());
                    for (int i = 0; i < counties.size(); i++) {
                        CountyDBHelper countyDBHelper = new CountyDBHelper();
                        countyDBHelper.setCountyName(counties.get(i).getCountyName());
                        countyDBHelper.setWeatherId(counties.get(i).getWeatherId());
                        countyDBHelper.setCityId(selectCity.getCityCode());
                        countyDBHelper.save();
                    }
                    queryCounty();
                }
            }
        });
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG, "onStop");
        if (client != null)
            client.stop();
    }
}
